package com.bb.flow.service.imp.executor.node;

import com.bb.flow.api.type.ExecuteState;
import com.bb.flow.config.AbstractConfigNode;
import com.bb.flow.config.ConditionInfo;
import com.bb.flow.config.FlowInfo;
import com.bb.flow.config.enumtype.NodeType;
import com.bb.flow.config.node.JudgeConfigNode;
import com.bb.flow.service.api.NodeStateCallback;
import com.bb.flow.service.imp.AbstractNodeExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author bigbeard
 * 判断节点执行器
 */
public class JudgeNodeExecutor extends AbstractNodeExecutor {
    private final static Logger logger = LoggerFactory.getLogger(JudgeNodeExecutor.class);

    private static final String EXECUTE_JUDGE_NODE_THREAD = "execute-judge-node-thread-%s";

    @Override
    protected String getThreadName() {
        return EXECUTE_JUDGE_NODE_THREAD;
    }

    /**
     * 执行判断节点,并此处不会真正调用判读节点的判断和计算
     *
     * @param node              执行节点
     * @param flowInfo          流程信息
     * @param nodeStateCallback 执行状态回调通知接口
     */
    @Override
    protected void executeNode(
            AbstractConfigNode node, FlowInfo flowInfo
            , NodeStateCallback nodeStateCallback) {
        if (canExecute(node)) {
            return;
        }
        this.setNodeStateCallback(nodeStateCallback);
        this.setCurrentFlowInfo(flowInfo);
        this.setCurrentNode(node);
        flowInfo.getFlowContext().setNodeKey(node.getNodeKey());

        notifyExecuteState(ExecuteState.EXECUTING);
        JudgeConfigNode judgeConfigNode = (JudgeConfigNode) node;

        ConditionInfo condition = judgeConfigNode.getCondition();
        if (null == condition) {
            logger.error("流程模版[{}]中的判断节点[{}]未配置判断信息,请检查[Condition]配置信息", flowInfo.getFlowTemplateName(),
                    node.getNodeKey());
            notifyExecuteState(ExecuteState.EXCEPTION);
            return;
        }
        notifyExecuteState(ExecuteState.FINISH);
    }

    /**
     * 节点类型
     *
     * @return 节点类型
     */
    @Override
    protected NodeType getAllowExecuteNodeType() {
        return NodeType.JUDGE_NODE;
    }

}
